﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

using System.IO;



namespace RecipeRecommender
{
    class CCaseLoader
    {
        String cIngredientFileString = "../../Data/IngredientList.txt";
        String cCaseLibraryFileString = "../../Data/CaseLibrary.txt";

        public CCaseLoader()
        {
            cSelectedRecipes = new List<CRecipe>();

            cIngredientList = new List<CIngredient>();
            cRecipeList = new List<CRecipe>();

            readIngredientList();

            readCases();
            //cIngredientStrings = new Hashtable();
            //cRecipeList = new List<CRecipe>();
            //CIngredient[] cIng = { Ingredient.PORK, Ingredient.SPINACH };
            //AddRecipe (Cuisine.WESTERN, cIng , MealType.MAIN, "Spinach Pork");

            //CIngredient[] cIng2 = { Ingredient.RED_BEAN };
            //AddRecipe(Cuisine.CHINESE, cIng2, MealType.DESSERT, "RED Bean Soup");

            //CIngredient[] cIng3 = { Ingredient.CHICKEN, Ingredient.CABBAGE };
            //AddRecipe(Cuisine.CHINESE, cIng3, MealType.SIDE, "Chicken Cabbage");
           
            //CIngredient[] cIng4 = {new CCabbage(), new CSpinach()};
            //AddRecipe (Cuisine.CHINESE, cIng4, MealType.SIDE, "Spinach Cabbage soup");


            //CIngredient[] cIng5 = { new CMeat(), new CSpinach() };
            //AddRecipe(Cuisine.WESTERN, cIng5, MealType.SIDE, "Spinach Meat dish");

            //CIngredient[] cIng6 = { new CChicken(), new CCabbage() };
            //AddRecipe(Cuisine.WESTERN, cIng6, MealType.SIDE, "Chicken Cabbage Casserole");

            //CIngredient[] cIng7 = { new CBeef()};
            //AddRecipe(Cuisine.WESTERN, cIng7, MealType.SIDE, "Beef Stew");

            //CIngredient[] cIng8 = { new CPork(), new CSpinach() };
            //AddRecipe(Cuisine.WESTERN, cIng8, MealType.SIDE, "Fried Spinach Pork");


        }

        public void readIngredientList()
        {
            TextReader cReader = new StreamReader(cIngredientFileString);

            String strLine;

            strLine = cReader.ReadLine();

            while (strLine != null && strLine != "")
            {

                int nIndex = strLine.LastIndexOf('-');

                int nStartIndex = nIndex + 1;

                int nLastIndex = strLine.IndexOf(':');

                String strName = strLine.Substring(nStartIndex, nLastIndex - nStartIndex);

                nStartIndex = nLastIndex + 1;

                String strValue = strLine.Substring(nStartIndex, strLine.Length - nStartIndex);

                CIngredient cIng = new CIngredient(strName, strValue);
                cIngredientList.Add(cIng);


                strLine = cReader.ReadLine();
            };
        }

        public void readCases()
        {
            TextReader cReader2 = new StreamReader(cCaseLibraryFileString);

            String strLine2 = cReader2.ReadLine();
            while (strLine2 != null && strLine2 != "")
            {
                CRecipe cRec = new CRecipe();

                //recipe name

                int nStartIndex = strLine2.IndexOf('|');

                String strName = strLine2.Substring(0, nStartIndex);

                cRec.name = strName;

                //cuisine

                nStartIndex = nStartIndex + 1;
                int nNextIndex = strLine2.IndexOf('|', nStartIndex);
                String strCuisine = strLine2.Substring(nStartIndex, nNextIndex - nStartIndex);
                cRec.setCuisine(strCuisine);

                //meal type
                nStartIndex = nNextIndex + 1;
                nNextIndex = strLine2.IndexOf('|', nStartIndex);
                String strMealType = strLine2.Substring(nStartIndex, nNextIndex - nStartIndex);
                cRec.setMealType(strMealType);


                //cooking method

                nStartIndex = nNextIndex + 1;
                nNextIndex = strLine2.IndexOf('|', nStartIndex);

                String strCookMeth = strLine2.Substring(nStartIndex, nNextIndex - nStartIndex);
                cRec.setCookingMethod(strCookMeth);

                //ingredients

                nStartIndex = nNextIndex + 1;
                nNextIndex = strLine2.IndexOf('|', nStartIndex);
                String strIng = strLine2.Substring(nStartIndex, nNextIndex - nStartIndex);

                String[] strWords = strIng.Split(',');

                List<CIngredient> cRecIng = new List<CIngredient>();

                foreach (String strTemp in strWords)
                {
                    CIngredient cIng = findIngredient(strTemp);
                    if (cIng != null)
                    {
                        cRecIng.Add(cIng);
                    }
                }

                cRec.ingredients = cRecIng;


                //spicy non spicy
                nStartIndex = nNextIndex + 1;
                nNextIndex = strLine2.IndexOf('|', nStartIndex);
                String strSpicy = strLine2.Substring(nStartIndex, nNextIndex - nStartIndex);
                cRec.setSpicy(strSpicy);

                //halal non halal
                nStartIndex = nNextIndex + 1;
                nNextIndex = strLine2.IndexOf('|', nStartIndex);
                String strHalal = strLine2.Substring(nStartIndex, nNextIndex - nStartIndex);
                cRec.setHalal(strHalal);

                //healthy non healthy
                nStartIndex = nNextIndex + 1;
                nNextIndex = strLine2.IndexOf('|', nStartIndex);
                String strHealthy = strLine2.Substring(nStartIndex, nNextIndex - nStartIndex);
                cRec.setHealthy(strHealthy);


                //non vegetarian vegetarian
                nStartIndex = nNextIndex + 1;
                nNextIndex = strLine2.IndexOf('|', nStartIndex);
                String strVegetarian = strLine2.Substring(nStartIndex, nNextIndex - nStartIndex);
                cRec.setVegetarian(strVegetarian);

                //cooking time
                nStartIndex = nNextIndex + 1;
                nNextIndex = strLine2.IndexOf('|', nStartIndex);
                String strCookingTime = strLine2.Substring(nStartIndex, nNextIndex - nStartIndex);
                cRec.cookingTime = Double.Parse(strCookingTime);

                //serving size
                nStartIndex = nNextIndex + 1;
                nNextIndex = strLine2.IndexOf('|', nStartIndex);
                String strServingSize = strLine2.Substring(nStartIndex, nNextIndex - nStartIndex);
                cRec.servings = Int16.Parse(strServingSize);

                //link
                nStartIndex = nNextIndex + 1;
                String strLink = strLine2.Substring(nStartIndex, strLine2.Length - nStartIndex);


                cRec.webLink = strLink;

                cRecipeList.Add(cRec);










                strLine2 = cReader2.ReadLine();
            }
            
        }

        public CIngredient findIngredient(String strIng)
        {
            foreach(CIngredient cIngredient in cIngredientList)
            {
                if (strIng.ToLower() == cIngredient.getString().ToLower())
                {
                    return cIngredient;
                }
            }
            return null;
        }

        public void loadStrings()
        {
            //cIngredientStrings.Add(Ingredient.PORK, "Pork");
            //cIngredientStrings.Add(Ingredient.VEGETABLE, "Vegetable");
            //cIngredientStrings.Add(Ingredient.BROCOLLI, "Brocolli");
            
        }

        public List<CRecipe> cSelectedRecipes;

        public List<CRecipe> getRelevantCases(CRecipe cQuery)
        {

            cSelectedRecipes.Clear();

            foreach (CRecipe cRec in cRecipeList)
            {
                double dSim = getSimilarity(cRec, cQuery);
                cRec.Similarity = dSim;

                cSelectedRecipes.Add(cRec);
            }
            return cSelectedRecipes;
        }

        public double getSimilarity(CRecipe cCompare, CRecipe cQuery)
        {
            List<CIngredient> cQueryIngredients;
            List<CIngredient> cCompareIngredients;

            cCompareIngredients = cCompare.ingredients;

            cQueryIngredients = cQuery.ingredients;

            int nNoOfFieldsCompared=3;// value must be changed according to no of fields compared

            double dSimilarity = 0;

            //foreach (CIngredient cQueryIng in cQueryIngredients)
            //{
            //    foreach (CIngredient cCompareIng in cCompareIngredients)
            //    {
            //        if (cCompareIng.GetType() == cQueryIng.GetType())
            //        {
            //            dSimilarity += 5;
            //        }
            //        if (cCompareIng.GetType().BaseType == cQueryIng.GetType().BaseType)
            //        {
            //            dSimilarity += 3;
            //        }
            //    }
            //}
            double dFieldSimilarity;

            //cuisine
            dFieldSimilarity = 100 - ((double)System.Math.Abs(cCompare.cuisine - cQuery.cuisine) /(double) 4 * 100);

            dSimilarity += dFieldSimilarity;
            dFieldSimilarity = 100 - ((double)System.Math.Abs(cCompare.mealType - cQuery.mealType) / (double)2 * 100);
            dSimilarity += dFieldSimilarity;

            dFieldSimilarity = 100 - ((double)System.Math.Abs(cCompare.cookingMethod - cQuery.cookingMethod)/(double)4 * 100) ;
            dSimilarity += dFieldSimilarity;

            //
            //

            dSimilarity = dSimilarity / nNoOfFieldsCompared;

            return dSimilarity;
        }

        void AddRecipe(Cuisine cCuisine, CIngredient[] cIng, MealType cType, String strName)
        {
            //CRecipe r1 = new CRecipe();
            //r1.cuisine = cCuisine;
            //List<CIngredient> cIngredients = new List<CIngredient>();
            //for (int i = 0; i < cIng.Length; i++)
            //{
            //    cIngredients.Add(cIng[i]);
            //}
            
            //r1.ingredients = cIngredients;
            //r1.mealType = cType;
            //r1.name = strName;
            //cRecipeList.Add(r1);
        }

        private List<CRecipe> cRecipeList;
        private List<CIngredient> cIngredientList;
        public List<CIngredient> ingredientList
        {
            get { return cIngredientList; }
            set { cIngredientList = value; }
        }
    }
}
